﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lanting.Model;
using System.Collections;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid;
using System.IO;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using Lanting.Utilities;

namespace LantingConnect
{
    public partial class UC_Grid : UserControl
    {
        #region 全局变量、常量
        public int pageNo { get { return uC_PageNavigation.pageNo; } }
        public int opsPageNo { get { return uC_PageNavigation.opsPageNo; } }
        public int pageSize { get { return uC_PageNavigation.pageSize; } }
        public int totalDatas { get { return uC_PageNavigation.totalDatas; } } 
        public GridView getGridView { get { return gridview; } }
        public GridControl getGrid { get { return grid; } }
        public DevExpress.Data.DataController getDataController { get { return gridview.DataController; } }
        #endregion

        #region 外部接口-自定义事件
        //数据刷新
        public delegate void OnDataRefreshEvent();
        public event OnDataRefreshEvent OnDataRefresh;
        //列表-点击
        public delegate void OnGridClickEvent(object sender, EventArgs e);
        public event OnGridClickEvent OnGridClick;
        //列表视图-绘制行号
        public delegate void OnGridViewDrawIndicatorEvent(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e);
        public event OnGridViewDrawIndicatorEvent OnGridViewDrawIndicator;
        //列表视图-双击
        public delegate void OnGridViewDoubleClickEvent(object sender, EventArgs e);
        public event OnGridViewDoubleClickEvent OnGridViewDoubleClick;
        //视图列表-单元格编辑器双击
        public delegate void OnColumnEditDoubleClickeEvent(object sender, EventArgs e);
        public event OnColumnEditDoubleClickeEvent OnColumnEditDoubleClick;
        
        //列表视图-滚轮滚动
        public delegate void OnGridViewMouseWheelEvent(object sender, MouseEventArgs e);
        public event OnGridViewMouseWheelEvent OnGridViewMouseWheel;
        //列表视图-焦点行改变
        public delegate void OnFocusedRowChangedEvent(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e);
        public event OnFocusedRowChangedEvent OnFocusedRowChanged;
        //列表视图-单元格样式绘制
        public delegate void OnRowCellStyleEvent(object sender, RowCellStyleEventArgs e);
        public event OnRowCellStyleEvent OnRowCellStyle;
        //列表视图-单元格绘制
        public delegate void OnCustomDrawCellEvent(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e);
        public event OnCustomDrawCellEvent OnCustomDrawCell;
        //列表视图-单元格编辑器自定义
        public delegate void OnCustomRowCellEditEvent(object sender, CustomRowCellEditEventArgs e);
        public event OnCustomRowCellEditEvent OnCustomRowCellEdit;
        //列表视图-单元格按钮编辑器点击
        public delegate void OnColumnButtonClickEvent(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e);
        public event OnColumnButtonClickEvent OnColumnButtonClick;
        //列表视图-鼠标移动
        public delegate void OnMouseMoveEvent(object sender, MouseEventArgs e);
        public event OnMouseMoveEvent OnMouseMove;
        //列表视图-选中项改变
        public delegate void OnSelectionChangedEvent(object sender, DevExpress.Data.SelectionChangedEventArgs e);
        public event OnSelectionChangedEvent OnSelectionChanged;
        //列表视图-单元格值改变
        public delegate void OnCellValueChangedEvent(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e);
        public event OnCellValueChangedEvent OnCellValueChanged;
        //列表视图-分组排序自定义
        public delegate void OnCustomColumnSortEvent(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnSortEventArgs e);
        public event OnCustomColumnSortEvent OnCustomColumnSort;
        #endregion

        #region 用户控件初始化
        public UC_Grid()
        {
            InitializeComponent();

            //绑定单元格双击控件
            for (int i = 0; i < gridview.Columns.Count; i++)
            {
                if (gridview.Columns[i].ColumnEdit == null)
                {
                    gridview.Columns[i].ColumnEdit = format_doubleClick;
                }
            }
        }
        #endregion

        #region 事件-分页控件刷新
        private void uC_PageNavication_onRefreshClick(object sender, EventArgs e)
        {
            OnDataRefresh?.Invoke();
        }
        #endregion

        #region 事件-列表-点击
        private void grid_Click(object sender, EventArgs e)
        {
            OnGridClick?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-行号绘制
        private void gridview_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            Function_DrawRowIndicator_ByPage(sender, e, pageNo, pageSize);
            OnGridViewDrawIndicator?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-双击
        private void gridview_DoubleClick(object sender, EventArgs e)
        {
            gridview.SelectRow(gridview.FocusedRowHandle);
            OnGridViewDoubleClick?.Invoke(sender,e);
        }
        #endregion 

        #region 事件-列表视图-单元格编辑器双击
        private void format_doubleClick_DoubleClick(object sender, EventArgs e)
        {
            gridview.SelectRow(gridview.FocusedRowHandle);
            OnColumnEditDoubleClick?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-单元格绘制
        private void gridview_CustomDrawCell(object sender, DevExpress.XtraGrid.Views.Base.RowCellCustomDrawEventArgs e)
        {
            OnCustomDrawCell?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-单元格编辑器自定义
        private void gridview_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
        {
            OnCustomRowCellEdit?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-滚轮滚动
        private void gridview_MouseWheel(object sender, MouseEventArgs e)
        {
            gridview.CloseEditor();
            gridview.UpdateCurrentRow();
            OnGridViewMouseWheel?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-焦点行改变
        private void gridview_FocusedRowChanged(object sender, DevExpress.XtraGrid.Views.Base.FocusedRowChangedEventArgs e)
        {
            OnFocusedRowChanged?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-单元格样式绘制
        private void gridview_RowCellStyle(object sender, RowCellStyleEventArgs e)
        {
            OnRowCellStyle?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-单元格按钮编辑器点击
        private void format_button_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            OnColumnButtonClick?.Invoke(sender, e);
        }
        private void format_button_Click(object sender, EventArgs e)
        {
            OnColumnButtonClick?.Invoke(sender, null);
        }
        #endregion

        #region 事件-列表视图-鼠标移动
        private void gridview_MouseMove(object sender, MouseEventArgs e)
        {
            OnMouseMove?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-选中项改变
        private void gridview_SelectionChanged(object sender, DevExpress.Data.SelectionChangedEventArgs e)
        {
            OnSelectionChanged?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-单元格值改变
        private void gridview_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            OnCellValueChanged?.Invoke(sender, e);
        }
        #endregion

        #region 事件-列表视图-分组排序自定义
        private void gridview_CustomColumnSort(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnSortEventArgs e)
        {
            OnCustomColumnSort?.Invoke(sender, e);
        }
        #endregion

        #region 外部方法-初始化分页控件
        public void Function_InitPageNavigation()
        {
            uC_PageNavigation.Function_InitPageNavigation();
        }
        #endregion

        #region 外部方法-设置加载中
        public void Function_SetLoading(bool isLoading)
        {
            if (isLoading)
            {
                gridview.ShowLoadingPanel();
            }
            else
            {
                gridview.HideLoadingPanel();
            }
        }
        #endregion

        #region 外部方法-生成数据列
        /// <summary>
        /// 生成数据列
        /// </summary>
        /// <param name="list">数据列对象集合</param>
        /// <param name="isCheckBox">是否多选框模式</param>
        /// <param name="fileName">布局文件名</param>
        /// <param name="isPaging">是否分页</param>
        public void Function_CreateCloumns(List<ColumnData> list,bool isCheckBox,bool isPaging,string fileName)
        {    
            //是否多选框模式        
            if (isCheckBox)
            {
                //多选框模式
                gridview.OptionsSelection.MultiSelectMode = GridMultiSelectMode.CheckBoxRowSelect;
                gridview.OptionsSelection.CheckBoxSelectorColumnWidth = 30;
            }
            //是否不分页
            if (!isPaging)
            {
                uC_PageNavigation.Visible = false;
                uC_PageNavigation.pageSize = Params.PageSizeMax;
            }
            DevExpress.XtraGrid.Columns.GridColumn column;
            int i = 0;
            foreach (ColumnData item in list)
            {
                column = new DevExpress.XtraGrid.Columns.GridColumn();
                gridview.Columns.Add(column);
                column.Name = item.name;
                column.FieldName = item.fieldName;
                column.Caption = item.caption;
                //是否隐藏
                if (item.isVisible)
                {
                    column.Visible = true;
                    column.VisibleIndex = i;
                    i++;
                }
                else
                {
                    column.Visible = false;
                    column.VisibleIndex = -1;
                }
                //日期格式
                switch (item.columnEditType)
                {
                    case ColumnEditType.dateTime:
                        column.ColumnEdit = format_datetime;
                        break;
                    case ColumnEditType.date:
                        column.ColumnEdit = format_date;
                        break;
                    case ColumnEditType.button:
                        column.ColumnEdit = format_button;
                        column.AppearanceCell.Font = new System.Drawing.Font("微软雅黑", 9F, System.Drawing.FontStyle.Bold);
                        break;
                }
                //单元格双击格式
                if (column.ColumnEdit == null)
                {
                    column.ColumnEdit = format_doubleClick;
                }
            }
                        
            //加载布局文件
            string path = Application.StartupPath + "\\LayoutXmls\\";
            if (Directory.Exists(path) && File.Exists(path + fileName + ".xml"))
            {
                gridview.RestoreLayoutFromXml(path + fileName + ".xml");
            }
        }
        #endregion

        #region 外部方法-绑定数据源并自适应(有布局文件除外)
        /// <summary>
        /// 绑定数据源
        /// </summary>
        /// <typeparam name="T">成员对象</typeparam>
        /// <param name="list">数据源列表</param>
        /// <param name="total">数据总数</param>
        /// <param name="fileName">布局文件名</param>
        public void Function_BindDataSource(IList list, int total, string fileName)
        {
            //绑定数据源
            if (list != null && list.Count > 0)
            {
                grid.DataSource = list;
            }
            else
            {
                uC_PageNavigation.Function_InitPageNavigation();
                grid.DataSource = null;
            }
            grid.RefreshDataSource();

            //分页处理
            uC_PageNavigation.Function_RefreshPageNavigation(pageSize, total);
            //刷新分页控件样式
            uC_PageNavigation.refreshStyles();

            //数据加载完毕
            gridview.HideLoadingPanel();

            //无布局文件则自适应
            string path = Application.StartupPath + "\\LayoutXmls\\";
            if (!(Directory.Exists(path) &&File.Exists(path + fileName + ".xml")))
            {
                gridview.BestFitColumns();
            }
        }
        #endregion

        #region 外部方法-保存布局文件
        public void Function_SaveLayout(string fileName)
        {
            string path = Application.StartupPath + "\\LayoutXmls\\";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            gridview.SaveLayoutToXml(path + fileName + ".xml");
        }
        #endregion

        #region 外部方法-导出GridView文件到桌面
        /// <summary>
        /// 导出GridView文件到桌面
        /// </summary>
        /// <param name="fileName">文件名(不含后缀名)</param>
        public void Function_ExportToXls(string _fileName)
        {
            string fileName = _fileName + DateTime.Now.ToString("yyyyMMddHH");
            SaveFileDialog saveDialog = new SaveFileDialog();
            saveDialog.RestoreDirectory = true;
            saveDialog.DefaultExt = "xls|xlsx";
            saveDialog.Filter = "Excel文件 97-2003|*.xls|Excel文件|*.xlsx";
            saveDialog.FileName = fileName;
            saveDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            if (saveDialog.ShowDialog() == DialogResult.OK)
            {
                if (saveDialog.FilterIndex == 1)
                {
                    gridview.ExportToXls(saveDialog.FileName);
                    //导出后打开文件
                    System.Diagnostics.Process.Start(saveDialog.FileName);
                }
                else if (saveDialog.FilterIndex == 2)
                {
                    gridview.ExportToXlsx(saveDialog.FileName);
                    //导出后打开文件
                    System.Diagnostics.Process.Start(saveDialog.FileName);
                }
            }
        }
        #endregion

        #region 外部方法-获取Grid选中行List数据集
        public List<L> Function_GetGridViewSelctions<L>()
        {
            try
            {
                int[] int_rows = gridview.GetSelectedRows();
                List<L> newlist = new List<L>();

                foreach (int row in int_rows)
                {
                    L rowdata = (L)gridview.GetRow(row);
                    newlist.Add(rowdata);
                }
                return newlist;
            }
            catch (Exception ex)
            {
                UtilMethods.CatchException(ex);
                return null;
            }
        }
        #endregion

        #region 外部方法-获取击中行信息
        public GridHitInfo Function_CalcHitInfo(object sender, EventArgs e)
        {
            MouseEventArgs arg = e as MouseEventArgs;
            GridHitInfo hitinfo = gridview.CalcHitInfo(new Point(arg.X, arg.Y));
            return hitinfo;
        }
        #endregion

        #region 外部方法-获取击中行数据
        public T Function_GetHitRow<T>(object sender, EventArgs e)
        {
            //获取击中行信息
            DevExpress.XtraGrid.Views.Grid.ViewInfo.GridHitInfo hitInfo = Function_CalcHitInfo(sender, e);
            T rowInfo;
            if (hitInfo.InDataRow)
            {
                rowInfo = (T)gridview.GetRow(hitInfo.RowHandle);
                return rowInfo;
            }
            else
            {
                return default(T);
            }
        }
        #endregion        

        #region 内部方法-GridView行号绘制
        private void Function_DrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            if (e.Info.IsRowIndicator && e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1).ToString();
            }
        }
        #endregion

        #region 内部方法-GridView行号绘制-分页
        private void Function_DrawRowIndicator_ByPage(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e, int pageNo, int pageSize)
        {
            if (e.Info.IsRowIndicator && e.RowHandle >= 0)
            {
                e.Info.DisplayText = (e.RowHandle + 1 + (pageNo - 1) * pageSize).ToString();
            }
        }




        #endregion

        
    }
}
